﻿using DllInject.Properties;
using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace DllInject
{
    class Injector
    {


        //为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
        static Int32 MEM_COMMIT = 0x1000;

        //保留进程的虚拟地址空间，而不分配任何物理存储。保留页面可通过继续调用VirtualAlloc（）而被占用
        static Int32 MEM_RESERVE = 0x2000;

        static Int32 MEM_RELEASE = 0x8000;

        //区域包含可执行代码，应用程序可以读写该区域。
        static Int32 PAGE_EXECUTE_READWRITE = 0x40;

        static UInt32 INFINITE = 0xFFFFFFFF;


        public static void Inject(int pid,string dll,ulong loadFun) {

            IntPtr handle;
            IntPtr ThreaHanle;
            bool status;
            int AllocBaseAddress;
            int LoadLibraryAddress;
            string Function = "LoadLibraryA";
            try
            {
                
                handle = Process.GetProcessById(pid).Handle;
                Console.WriteLine(handle);

                AllocBaseAddress = Native.VirtualAllocEx(handle, 0, dll.Length + 1, MEM_COMMIT + MEM_RESERVE, PAGE_EXECUTE_READWRITE);
                    if (AllocBaseAddress == 0)
                    {
                        MessageBox.Show("Alloc memory failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    status = Native.WriteProcessMemory(handle, AllocBaseAddress, dll, dll.Length + 1, 0);
                    if (!status)
                    {
                        MessageBox.Show("Write memory failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    LoadLibraryAddress = Native.GetProcAddress((int)loadFun, Function);
                    if (LoadLibraryAddress == 0)
                    {
                        MessageBox.Show("Get function \"LoadLibraryA\" address failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    ThreaHanle = Native.CreateRemoteThread(handle, 0, 0, LoadLibraryAddress, AllocBaseAddress, 0, 0);
                    if (ThreaHanle == IntPtr.Zero)
                    {
                        MessageBox.Show("Have Injected failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    Native.WaitForSingleObject(ThreaHanle, INFINITE);
                    Native.VirtualFree(handle, 0, MEM_RELEASE);
            }
            catch
            {
            }

        }

        public static void Uninject(int pid, ulong dllHand) { 
            //string FreeLibrary = "FreeLibrary ";
            //IntPtr handle;
            //IntPtr ThreaHanle;
            //bool status;
            //int AllocBaseAddress;
            //int LoadLibraryAddress;
            //string Function = "LoadLibraryA";
            //try
            //{

            //    handle = Process.GetProcessById(pid).Handle;


            //    LoadLibraryAddress = Native.GetProcAddress(Native.GetModuleHandleA("kernel32.dll"), Function);
            //    if (LoadLibraryAddress == 0)
            //    {
            //        MessageBox.Show("Get function \"LoadLibraryA\" address failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //        return;
            //    }

            //    ThreaHanle = Native.CreateRemoteThread(handle, 0, 0, LoadLibraryAddress, , 0, 0);
            //    if (ThreaHanle == IntPtr.Zero)
            //    {
            //        MessageBox.Show("Have Injected failure", "Message:", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //        return;
            //    }
            //    Native.WaitForSingleObject(ThreaHanle, INFINITE);
            //    Native.VirtualFree(handle, 0, MEM_RELEASE);
            //}
            //catch
            //{
            //}
        }
    }
}
